package com.scedu.config;

import com.scedu.entity.User;
import com.scedu.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

//自定义的Realm
//继承AuthorizingRealm
//重写方法 授权 认证
//@Slf4j
public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //、、 log.info("执行了授权");
        System.out.println("执行了授权 doGetAuthorizationInfo "+principalCollection.hashCode());
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();

        //1.拿到当前登录的对象
        Subject  subject= SecurityUtils.getSubject();
        System.out.println("2.subject="+subject.hashCode());
        //通过 return new SimpleAuthenticationInfo(user,user.getPassword(),"");
        User currentUser =(User) subject.getPrincipal();//拿到user对象
        //设置当前用户的权限
       // info.addStringPermission(currentUser.getPerms());
        return info;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了认证 doGetAuthenticationInfo ");

        //1、把方法的authenticationToken参数转换为UsernamePasswordToken类型
        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
        System.out.println("usertoen="+userToken);
        System.out.println("userToken.getUsername()="+userToken.getUsername());
        //2、UsernamePasswordToken中获取username
        String username=userToken.getUsername();
        char[] password = userToken.getPassword();
        //3、调用数据库方法，去数据库中查询username对应的用户记录
        User user= userService.findByUserName(username);
        //4、若用户不存在，则抛出unknownaccountException
        if(user==null){
            System.out.println("没有这个人"); //没有这个人
            return null; //底层会throw new UnknownAccountException("用户不存在");

        }
        //5、根据用户信息的情况，决定是否抛出其他的authenticationException异常
        if(user.getUsername().equals("locked")){
            System.out.println("被锁定"); //用户被锁定
            throw  new LockedAccountException("用户被锁定");
        }

        //密码校验shiro做
        //6、根据用户的情况，来构建AuthenticationInfo对象返回
        //以下信息是从数据库中获取的
       // 1） principal:认证的实体信息.可以是username，也可以是数据库对应的实体类对象
        Object principal=user; // Object principal=user;
        //2)credentials:数据库中的密码
        Object credentials=user.getPassword();
        //3)realmName :当前realm 对象的name 调用父类的getname方法即可
        String realmName=getName();
        return new SimpleAuthenticationInfo(principal,credentials,realmName);
    }
}
